#include "imgpreprocessing.h"

ImgPreProcessing::ImgPreProcessing(const Mat img)
{
    if(img.cols <=0 || img.rows <= 0)
        qDebug()<<"Couldn't find image !";

    gray_average = 0.0;

    src_image = img;

    cols = img.cols;
    rows = img.rows;

    resizeGrayValue(rows,cols);
}

void ImgPreProcessing::inRangeHSV()
{
    hsv_image = Mat(Scalar(cols,rows));
    cvtColor(src_image,hsv_image,CV_BGR2HSV);
    inRange(hsv_image,hsv_min,hsv_max,hsv_image);
    hsv_image = ~hsv_image;
    Mat srcSubHsv_image = Mat(Scalar(cols,rows));
    srcSubHsv_image = src_image.clone();
    for (int i =0 ;i < cols;i ++)
    {
        for (int j = 0;j < rows;j ++)
        {
            if(hsv_image.at<uchar>(i,j) != 255)
            {
                srcSubHsv_image.at<Vec3b>(i,j)[0] = 0;
                srcSubHsv_image.at<Vec3b>(i,j)[1] = 0;
                srcSubHsv_image.at<Vec3b>(i,j)[2] = 0;
            }
        }
    }
//    imshow("Sub",srcSubHsv_image);
//    cvtColor(srcSubHsv_image,srcSubHsv_image,CV_BGR2HSV);
//    inRange(srcSubHsv_image,face_hsv_min,face_hsv_max,srcSubHsv_image);
//    imshow("subbbbb",srcSubHsv_image);
//    hsv_image = srcSubHsv_image.clone();
}

Rect ImgPreProcessing::imgMorphology()
{
    morphology_image = hsv_image.clone();

    // open
    int open_x = 7;
    int open_y = 7;
    Mat open_kernel = getStructuringElement(MORPH_RECT,Size(open_x,open_y));
    morphologyEx(morphology_image,morphology_image,CV_MOP_OPEN,open_kernel);

    //close
    int close_x = 3;
    int close_y = 3;
    Mat close_kernel = getStructuringElement(MORPH_RECT,Size(close_x,close_y));
    morphologyEx(morphology_image,morphology_image,CV_MOP_CLOSE,close_kernel);


    for (int i =0 ;i < cols;i ++)
    {
        for (int j = 0;j < rows;j ++)
        {
            if(morphology_image.at<uchar>(i,j) == 255)
            {

//                qDebug()<<i<<" "<<j<<" "<<morphology_image.at<uchar>(i,j);

                binary_x.push_back(j);
                binary_y.push_back(i);
            }
        }
    }

    sort(binary_x.begin(),binary_x.end());
    sort(binary_y.begin(),binary_y.end());

//    qDebug()<<binary_x[0]<<","<<binary_y[0];
//    qDebug()<<binary_x[binary_x.size() - 1]<<","<<binary_y[binary_y.size() - 1];
    Rect rect(binary_x[0],binary_y[0],binary_x[binary_x.size() - 1] - binary_x[0],binary_y[binary_y.size() - 1] - binary_y[0]);

//    rectangle(src_image,rect,rect_color,line_width,LINE_8);

    return rect;
}

void ImgPreProcessing::makePreProcessing()
{
    inRangeHSV();
    imgCut(imgMorphology());
    cuttedImg2Gray();
    makeGrayValue();
    grayValueSubAverage();
    grayValue2Dec();
}

void ImgPreProcessing::imgCut(Rect rct)
{
    cut_image = Mat(src_image,rct);
    cv::resize(cut_image,cut_image,Size(cols,rows));
}

void ImgPreProcessing::cuttedImg2Gray()
{
    cvtColor(cut_image,gray_image,CV_BGR2GRAY);
}

void ImgPreProcessing::resizeGrayValue(int rows, int cols)
{
    gray_value.resize(rows*rows);
}

void ImgPreProcessing::makeGrayValue()
{
    for (int i =0 ;i < cols;i ++)
    {
        for (int j = 0;j < rows;j ++)
        {
            gray_value[i * cols + j] = gray_image.at<uchar>(i,j);
//            qDebug()<<i<<" "<<j<<gray_value[i * cols + j];
            gray_average += 1.0 * gray_value[i * cols + j];
        }
    }
    gray_average /= (cols * rows);
//    qDebug()<<gray_average;
}

void ImgPreProcessing::grayValueSubAverage()
{
    for (int i =0 ;i < cols;i ++)
    {
        for (int j = 0;j < rows;j ++)
        {
            if(gray_value[i * cols + j] > gray_average)
                gray_value[i * cols + j] -= gray_average;
            else
                gray_value[i * cols + j] = 0;
//            qDebug()<<i<<" "<<j<<gray_value[i * cols + j];
        }
    }
}

void ImgPreProcessing::grayValue2Dec()
{
    decentralized_image = gray_image.clone();
    for (int i =0 ;i < cols;i ++)
    {
        for (int j = 0;j < rows;j ++)
        {
            decentralized_image.at<uchar>(i,j) = gray_value[i * cols + j];
        }
    }
}


// get function

Mat ImgPreProcessing::getSrcImg()
{
    return src_image;
}

Mat ImgPreProcessing::getHSVImg()
{
    return hsv_image;
}

Mat ImgPreProcessing::getMorphologyImg()
{
    return morphology_image;
}

Mat ImgPreProcessing::getCutImg()
{
    return cut_image;
}

Mat ImgPreProcessing::getCuttedGrayImg()
{
    return gray_image;
}

Mat ImgPreProcessing::getDecentralizedImg()
{
    return decentralized_image;
}

int ImgPreProcessing::getSumnumber()
{
    return cols * rows;
}

vector<int> ImgPreProcessing::getGrayValue()
{
    return gray_value;
}

